﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ganaye.EmbeddedDb
{
    class Database : IDisposable
    {
        private static Database mDefaultDatabase;
        private static Database mCurrentDatabase;
        
        private bool mIsDisposed;
        private Dictionary<string, Table> mTablesByName;
        private Dictionary<string, Table> mTablesByPath;

        public static Database CurrentDatabase
        {
            get
            {
                if (mDefaultDatabase == null)
                {
                    mDefaultDatabase = new Database();
                    mCurrentDatabase = mDefaultDatabase;
                }
                return mCurrentDatabase;
            }
            set
            {
                mCurrentDatabase = value;
            }
        }

        public Database()
        {
            mTablesByName = new Dictionary<string, Table>(System.StringComparer.OrdinalIgnoreCase);
            mTablesByPath = new Dictionary<string, Table>(System.StringComparer.OrdinalIgnoreCase);
        }

        #region IDisposable Members
        
        public virtual void Dispose(bool isDisposing)
        {
            if (mIsDisposed) return;
            mIsDisposed = true;
            if (isDisposing)
            {
                // managed
            }
            //unmanaged
        }

        void IDisposable.Dispose()
        {
            if (mIsDisposed) return;
            GC.SuppressFinalize(this);
            Dispose(true);
        }

        ~Database()
        {
            Dispose(false);
        }
        #endregion

        internal Table<T> Table<T>() where T : Record
        {
            Table result=null;
            string tableName=typeof(T).Name;
            System.IO.FileInfo fi = new System.IO.FileInfo(tableName);
            string tablePath = fi.FullName;
            if (!mTablesByName.TryGetValue(tableName, out result))
            {
                var newTable = new Table<T>(tablePath);

                mTablesByName[tableName] = newTable;
                mTablesByPath[tablePath] = newTable;
                result = newTable;
            }
            return (Table<T>)result;
        }

        internal T NewRecord<T>() where T : Record
        {
            Table<T> table = Table<T>();
            return table.NewRecord(); 
        }
    }
}
